package cn.kgc.util.config;

import cn.kgc.security.AuthenticationFilter;
import cn.kgc.security.TokenAuthenticationFilter;
import cn.kgc.security.UsersDetailServiceImpl;
import cn.kgc.service.MenusService;
import cn.kgc.service.UsersService;
import cn.kgc.util.JwtUtil;
import cn.kgc.util.RedisUtil;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author YC
 * SpringSecurity配置类
 * 注解@EnableGlobalMethodSecurity(prePostEnabled = true) 开启方法级别的权限控制，没有权限会抛出异常
 */
@Component
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UsersDetailServiceImpl usersDetailService;
    @Resource
    private UsersService usersService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private MenusService menusService;

    /**
     * 配置请求拦截 认证管理器使用哪个对象进行认证
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 指定某些接口不需要通过验证即可访问。登陆接口肯定是不需要认证的
                .antMatchers("/users/login").permitAll()
                // 这里意思是其它所有接口需要认证才能访问
                .anyRequest().authenticated()
                .and()
                //关闭csrf跨站请求伪造
                .csrf().disable()
                //开启跨域以便前端调用接口
                .cors()
                .and()
                .addFilterBefore(
                        new TokenAuthenticationFilter(jwtUtil, redisUtil, usersService, menusService),
                        UsernamePasswordAuthenticationFilter.class)
                .addFilter(new AuthenticationFilter(authenticationManager(), jwtUtil))
                //禁用session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}
